package ejb;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

//import net.sf.jasperreports.engine.JRException;
import utils.ControlDTO;
import utils.DateUtils;
import utils.MensajeUtils;
//import utils.ReportUtils;
import constantes.Constantes;
import constantes.ConsultasDinamicasConstants;
import entidades.TActEconomica;
import entidades.TAdicion;
import entidades.TAfinacion;
import entidades.TAgudezaVisual;
import entidades.TAntecedente;
import entidades.TCatalogoMedicamento;
import entidades.TCiudad;
import entidades.TConstante;
import entidades.TControl;
import entidades.TDepartamento;
import entidades.TDiagnostico;
import entidades.TDiagnosticoManejo;
import entidades.TEmpresaSalud;
import entidades.TEstadoCivil;
import entidades.TExamenMotor;
import entidades.TGenero;
import entidades.TLensometria;
import entidades.TMedicamento;
import entidades.TMicroscopia;
import entidades.TOftalmoscopia;
import entidades.TParentesco;
import entidades.TPatologia;
import entidades.TPersona;
import entidades.TPrescripcion;
import entidades.TPrescripcionLentesContacto;
import entidades.TPrescripcionMedica;
import entidades.TProfesional;
import entidades.TQueratometria;
import entidades.TRefraccion;
import entidades.TSubjetivo;
import entidades.TTipDocumento;
import entidades.TTipLente;
import entidades.TTipOptotipo;
import entidades.TTipoMaterial;
import enumeraciones.SubTipoOptoTipoEnum;

/**
 * Session Bean implementation class AdministrarHistoriaBean
 */
@Stateless
@LocalBean
public class AdministrarHistoriaBean {

    @PersistenceContext(name = "Smerald2")
    EntityManager em;

    @SuppressWarnings("unchecked")
    public List<TControl> buscarControl(ControlDTO controlDTO) {
        StringBuilder consulta = new StringBuilder(
                ConsultasDinamicasConstants.CONSULTAR_CONTROL);
        boolean isAllNull = true;
        HashMap<String, Object> parametros = new HashMap<String, Object>();
        if (controlDTO.getIdPersona() != null) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_CONTROL_PARAM_ID_PERSONA);
            parametros.put("idPersona", controlDTO.getIdPersona());
            isAllNull = false;
        }
        if (controlDTO.getFechaInicial() != null) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_CONTROL_PARAM_FECHA_INICIO);
            parametros.put("fechaInicio", controlDTO.getFechaInicial());
            isAllNull = false;
        }
        if (controlDTO.getFechaFinal() != null) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_CONTROL_PARAM_FECHA_FIN);
            parametros.put("fechaFin", controlDTO.getFechaFinal());
            isAllNull = false;
        }

        consulta.append(ConsultasDinamicasConstants.CONSULTAR_CONTROL_PARAM_ORDER_BY);

        Query query = em.createQuery(consulta.toString());
        Set<String> keys = parametros.keySet();
        for (String llave : keys) {
            query.setParameter(llave, parametros.get(llave));
        }

        return (ArrayList<TControl>) query.getResultList();
    }

    public void crearPersona(TPersona personaCrear, TProfesional user) throws Exception {
        System.out.println("Antes de los IF");
        List<TPersona> personasExistentes = buscarPersona(personaCrear);

        if (personasExistentes != null && !personasExistentes.isEmpty() && personaCrear.getIdPersona() == null) {
            throw new Exception(MensajeUtils.getMensaje("personaExistente"));
        }

        if (personaCrear.getIdPersona() == null) {
            personaCrear.setUserCreacion(user.getUserName());
            personaCrear.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(personaCrear);
            System.out.println("Persistio");
        } else {
            personaCrear.setUserModificacion(user.getUserName());
            personaCrear.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(personaCrear);
        }
    }

    public void crearAntecedentes(List<TAntecedente> listaAntecedentes, TProfesional user) {
        if (listaAntecedentes != null && !listaAntecedentes.isEmpty()) {
            for (TAntecedente antecedente : listaAntecedentes) {
                if (antecedente.getIdAntecedente() == null) {
                    antecedente.setUserCreacion(user.getUserName());
                    antecedente.setFechaCreacion(Calendar.getInstance().getTime());
                    em.persist(antecedente);
                } else {
                    antecedente.setUserModificacion(user.getUserName());
                    antecedente.setFechaModificacion(Calendar.getInstance().getTime());
                    em.merge(antecedente);
                }
            }
        }
    }

    public void eliminarPersona(TPersona personaSelected) {
        em.remove(em.find(TPersona.class, personaSelected.getIdPersona()));
    }

    @SuppressWarnings("unchecked")
    public List<TPersona> buscarPersona(TPersona persona) {
        StringBuilder consulta = new StringBuilder(
                ConsultasDinamicasConstants.CONSULTAR_PERSONA);
        boolean isAllNull = true;
        HashMap<String, Object> parametros = new HashMap<String, Object>();

        if (persona.getNumeroHistoria() != null && persona.getNumeroHistoria().trim().length() > 0) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_PERSONA_PARAM_HISTORIA_CLINICA);
            parametros.put("historiaClinica", persona.getNumeroHistoria());
            isAllNull = false;
        }

        if (persona.getNumDocumento() != null
                && persona.getNumDocumento().trim().length() > 0) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_PERSONA_PARAM_NUMERO_IDENTIFICACION);
            parametros.put("numeroIdentificacion", persona.getNumDocumento());
            isAllNull = false;
        }
        if (persona.gettTipDocumento() != null) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_PERSONA_PARAM_TIPO_DOCUMENTO);
            parametros.put("tipoIdentificacion", persona.gettTipDocumento()
                    .getIdTipDocumento());
            isAllNull = false;
        }
        if (persona.getDesPrinombre() != null
                && persona.getDesPrinombre().trim().length() > 0) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_PERSONA_PARAM_PRIMER_NOMBRE);
            parametros.put("nombre", persona.getDesPrinombre());
            isAllNull = false;
        }
        if (persona.getDesSegnombre() != null
                && persona.getDesSegnombre().trim().length() > 0) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_PERSONA_PARAM_SEGUNDO_NOMBRE);
            parametros.put("segundoNombre", persona.getDesSegnombre());
            isAllNull = false;
        }
        if (persona.getDesPriapellido() != null
                && persona.getDesPriapellido().trim().length() > 0) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_PERSONA_PARAM_PRIMER_APELLIDO);
            parametros.put("primerApellido", persona.getDesPriapellido());
            isAllNull = false;
        }

        if (persona.getDesSegapellido() != null
                && persona.getDesSegapellido().trim().length() > 0) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_PERSONA_PARAM_SEGUNDO_APELLIDO);
            parametros.put("segundoApellido", persona.getDesSegapellido());
            isAllNull = false;
        }

        consulta.append(ConsultasDinamicasConstants.CONSULTAR_PERSONA_PARAM_ORDER_BY);

        Query query = em.createQuery(consulta.toString());
        Set<String> keys = parametros.keySet();
        for (String llave : keys) {
            query.setParameter(llave, parametros.get(llave));
        }

        return (ArrayList<TPersona>) query.getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TAntecedente> consultarAntecedentesPersona(TPersona persona) {
        return (ArrayList<TAntecedente>) em.createQuery(
                "select t from TAntecedente t "
                + " WHERE t.TPersona.idPersona =:idPersona ")
                .setParameter("idPersona", persona.getIdPersona())
                .getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TTipOptotipo> consultarTipoOptotipos(SubTipoOptoTipoEnum subtipo) {
        return (ArrayList<TTipOptotipo>) em.createQuery(
                "select to from TTipOptotipo to WHERE to.desSubTipOptotipo=:subtipo ORDER BY to.desTipOptotipo")
                .setParameter("subtipo", subtipo)
                .getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TTipLente> consultarTipoLentes() {
        return (ArrayList<TTipLente>) em.createQuery(
                "select tl from TTipLente tl ORDER BY tl.desTipLente").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TTipoMaterial> consultarTipoMateriales() {
        return (ArrayList<TTipoMaterial>) em.createQuery(
                "select tm from TTipoMaterial tm ORDER BY tm.desNombre").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TCatalogoMedicamento> consultarMedicamentos() {
        return (ArrayList<TCatalogoMedicamento>) em.createQuery(
                "select tm from TCatalogoMedicamento tm ").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TMedicamento> consultarMedicamentosPrescripcion(TPrescripcionMedica prescripcionMedica) {
        return (ArrayList<TMedicamento>) em.createQuery(
                "select tm from TMedicamento tm LEFT JOIN FETCH tm.catalogo catalogo "
                + " WHERE tm.prescripcion.idPrescripcionMed =:idPrescripcionMed ")
                .setParameter("idPrescripcionMed", prescripcionMedica.getIdPrescripcionMed())
                .getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TTipDocumento> consultarTiposDocumento() {
        return (ArrayList<TTipDocumento>) em.createQuery(
                "Select t FROM TTipDocumento t ORDER BY t.desTipDocumento").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TGenero> consultarGeneros() {
        return (ArrayList<TGenero>) em.createQuery("Select t FROM TGenero t ORDER BY t.desGenero")
                .getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TEstadoCivil> consultarEstadosCiviles() {
        return (ArrayList<TEstadoCivil>) em.createQuery(
                "Select t FROM TEstadoCivil t ORDER BY t.desEstadoCivil").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TEmpresaSalud> consultarEPS() {
        return (ArrayList<TEmpresaSalud>) em.createQuery(
                "Select t FROM TEmpresaSalud t ORDER BY t.desNomempresa").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TDepartamento> consultarDepartamentos() {
        return (ArrayList<TDepartamento>) em.createQuery(
                "Select t FROM TDepartamento t ORDER BY t.nombre").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TCiudad> consultarCiudades() {
        return (ArrayList<TCiudad>) em.createQuery(
                "Select t FROM TCiudad t LEFT JOIN FETCH t.TDepartamento dep ORDER BY t.nombre").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TActEconomica> consultarOcupaciones() {
        return (ArrayList<TActEconomica>) em.createQuery(
                "Select t FROM TActEconomica t ORDER BY t.desActEconomica").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TParentesco> consultarParentescos() {
        return (ArrayList<TParentesco>) em.createQuery(
                "Select t FROM TParentesco t ORDER BY t.desParentesco").getResultList();
    }

    @SuppressWarnings("unchecked")
    public List<TPatologia> consultarPatologias() {
        return (ArrayList<TPatologia>) em.createQuery(
                "Select t FROM TPatologia t ORDER BY t.desNombre").getResultList();
    }

    public void crearMotivoConsulta(TControl control, TProfesional user) {
        if (control.getIdControl() == null) {
            control.setUserCreacion(user.getUserName());
            control.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(control);
        } else {
            control.setUserModificacion(user.getUserName());
            control.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(control);
        }
    }

    public void crearAgudezaVisual(TAgudezaVisual agudezaVisual, TProfesional user) {
        validarControl(agudezaVisual.getTControl(), user);
        if (agudezaVisual.getIdAgudezaVisual() == null) {
            agudezaVisual.setUserCreacion(user.getUserName());
            agudezaVisual.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(agudezaVisual);
        } else {
            agudezaVisual.setUserModificacion(user.getUserName());
            agudezaVisual.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(agudezaVisual);
        }
    }

    public void crearLensometria(TLensometria lensometria, TProfesional user) {
        validarControl(lensometria.getTControl(), user);
        if (lensometria.getIdLensometria() == null) {
            lensometria.setUserCreacion(user.getUserName());
            lensometria.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(lensometria);
        } else {
            lensometria.setUserModificacion(user.getUserName());
            lensometria.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(lensometria);
        }
    }

    public void crearPrescripcion(TPrescripcion prescripcion, TProfesional user) {
        validarControl(prescripcion.getTControl(), user);
        if (prescripcion.getIdPrescripcion() == null) {
            prescripcion.setUserCreacion(user.getUserName());
            prescripcion.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(prescripcion);
        } else {
            prescripcion.setUserModificacion(user.getUserName());
            prescripcion.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(prescripcion);
        }
    }

    public void crearPrescripcionLentes(TPrescripcionLentesContacto prescripcion, TProfesional user) {
        validarControl(prescripcion.getTControl(), user);
        if (prescripcion.getIdPrescripcionLentes() == null) {
            prescripcion.setUserCreacion(user.getUserName());
            prescripcion.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(prescripcion);
        } else {
            prescripcion.setUserModificacion(user.getUserName());
            prescripcion.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(prescripcion);
        }
    }

    public void crearPrescripcionMedica(TPrescripcionMedica prescripcionMedica, TProfesional user) {
        validarControl(prescripcionMedica.getTControl(), user);
        if (prescripcionMedica.getIdPrescripcionMed() == null) {
            prescripcionMedica.setUserCreacion(user.getUserName());
            prescripcionMedica.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(prescripcionMedica);
        } else {
            prescripcionMedica.setUserModificacion(user.getUserName());
            prescripcionMedica.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(prescripcionMedica);
        }
    }

    public void guardarMedicamentos(List<TMedicamento> listaMedicamentosSelected, TProfesional user) {
        if (listaMedicamentosSelected != null && !listaMedicamentosSelected.isEmpty()) {
            for (TMedicamento medicamento : listaMedicamentosSelected) {
                if (medicamento.getIdMedicamento() == null) {
                    medicamento.setUserCreacion(user.getUserName());
                    medicamento.setFechaCreacion(Calendar.getInstance().getTime());
                    em.persist(medicamento);
                } else {
                    medicamento.setUserModificacion(user.getUserName());
                    medicamento.setFechaModificacion(Calendar.getInstance().getTime());
                    em.merge(medicamento);
                }
            }
        }
    }

    public void crearExamenMotor(TExamenMotor examenMotor, TProfesional user) {
        validarControl(examenMotor.getTControl(), user);
        if (examenMotor.getIdExamenMotor() == null) {
            examenMotor.setUserCreacion(user.getUserName());
            examenMotor.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(examenMotor);
        } else {
            examenMotor.setUserModificacion(user.getUserName());
            examenMotor.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(examenMotor);
        }
    }

    public void crearOftalmoscopia(TOftalmoscopia oftalmoscopia, TProfesional user) {
        validarControl(oftalmoscopia.getTControl(), user);
        if (oftalmoscopia.getIdOftalmoscopia() == null) {
            oftalmoscopia.setUserCreacion(user.getUserName());
            oftalmoscopia.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(oftalmoscopia);
        } else {
            oftalmoscopia.setUserModificacion(user.getUserName());
            oftalmoscopia.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(oftalmoscopia);
        }
    }

    public void crearBiomicroscopia(TMicroscopia biomicrocopia, TProfesional user) {
        validarControl(biomicrocopia.getTControl(), user);
        if (biomicrocopia.getIdMicroscopia() == null) {
            biomicrocopia.setUserCreacion(user.getUserName());
            biomicrocopia.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(biomicrocopia);
        } else {
            biomicrocopia.setUserModificacion(user.getUserName());
            biomicrocopia.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(biomicrocopia);
        }
    }

    public void crearQueratometria(TQueratometria queratometria, TProfesional user) {
        validarControl(queratometria.getTControl(), user);
        if (queratometria.getIdQueratometria() == null) {
            queratometria.setUserCreacion(user.getUserName());
            queratometria.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(queratometria);
        } else {
            queratometria.setUserModificacion(user.getUserName());
            queratometria.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(queratometria);
        }
    }

    public void crearRefraccion(TRefraccion refraccion, TProfesional user) {
        validarControl(refraccion.getTControl(), user);
        if (refraccion.getIdRefraccion() == null) {
            refraccion.setUserCreacion(user.getUserName());
            refraccion.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(refraccion);
        } else {
            refraccion.setUserModificacion(user.getUserName());
            refraccion.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(refraccion);
        }
    }

    public void crearSubjetivo(TSubjetivo subjetivo, TProfesional user) {
        validarControl(subjetivo.getTControl(), user);
        if (subjetivo.getIdSubjetivo() == null) {
            subjetivo.setUserCreacion(user.getUserName());
            subjetivo.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(subjetivo);
        } else {
            subjetivo.setUserModificacion(user.getUserName());
            subjetivo.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(subjetivo);
        }
    }

    public void crearAfinacion(TAfinacion afinacion, TProfesional user) {
        validarControl(afinacion.getTControl(), user);
        if (afinacion.getIdAfinacion() == null) {
            afinacion.setUserCreacion(user.getUserName());
            afinacion.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(afinacion);
        } else {
            afinacion.setUserModificacion(user.getUserName());
            afinacion.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(afinacion);
        }
    }

    public void crearAdicion(TAdicion adicion, TProfesional user) {
        validarControl(adicion.getTControl(), user);
        if (adicion.getIdAdicion() == null) {
            adicion.setUserCreacion(user.getUserName());
            adicion.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(adicion);
        } else {
            adicion.setUserModificacion(user.getUserName());
            adicion.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(adicion);
        }
    }

    public void crearDiagnosticoManejo(TDiagnosticoManejo diagnosticoManejo, TProfesional user) {
        validarControl(diagnosticoManejo.getTControl(), user);

        if (diagnosticoManejo.getIdDiagnosticoMedico() == null) {
            diagnosticoManejo.setUserCreacion(user.getUserName());
            diagnosticoManejo.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(diagnosticoManejo);
        } else {
            diagnosticoManejo.setUserModificacion(user.getUserName());
            diagnosticoManejo.setFechaModificacion(Calendar.getInstance().getTime());
            em.merge(diagnosticoManejo);
        }
    }

    public void crearDiagnosticos(List<TDiagnostico> listaDiagnosticos, TProfesional user) {
        if (listaDiagnosticos != null && !listaDiagnosticos.isEmpty()) {
            for (TDiagnostico diagnostico : listaDiagnosticos) {
                if (diagnostico.getIdDiagnostico() == null) {
                    diagnostico.setUserCreacion(user.getUserName());
                    diagnostico.setFechaCreacion(Calendar.getInstance().getTime());
                    em.persist(diagnostico);
                } else {
                    diagnostico.setUserModificacion(user.getUserName());
                    diagnostico.setFechaModificacion(Calendar.getInstance().getTime());
                    em.merge(diagnostico);
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public TAgudezaVisual consultarAgudezaVisual(TControl control) {
        List<TAgudezaVisual> agudezaList = (ArrayList<TAgudezaVisual>) em
                .createQuery(
                        "Select a FROM TAgudezaVisual a LEFT JOIN FETCH a.TTipOptotipo optotipo LEFT JOIN FETCH a.TTipoOptotipoVp optotipoVp "
                        + " LEFT JOIN FETCH a.TControl control "
                        + " WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (agudezaList != null && !agudezaList.isEmpty()) {
            return agudezaList.get(0);
        }

        TAgudezaVisual var = new TAgudezaVisual();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TLensometria consultarLensometria(TControl control) {
        List<TLensometria> lensometriaList = (ArrayList<TLensometria>) em
                .createQuery(
                        "Select a FROM TLensometria a LEFT JOIN FETCH a.tTipLente lente LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lensometriaList != null && !lensometriaList.isEmpty()) {
            return lensometriaList.get(0);
        }

        TLensometria var = new TLensometria();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TPrescripcion consultarPrescripcion(TControl control) {
        List<TPrescripcion> lista = (ArrayList<TPrescripcion>) em
                .createQuery(
                        "Select a FROM TPrescripcion a "
                        + " LEFT JOIN FETCH a.tTipLente lente "
                        + " LEFT JOIN FETCH a.tTipoMaterial material "
                        + " LEFT JOIN FETCH a.TControl control "
                        + " WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TPrescripcion var = new TPrescripcion();
        var.setTControl(control);
        return var;

    }

    @SuppressWarnings("unchecked")
    public TPrescripcionLentesContacto consultarPrescripcionLentes(TControl control) {
        List<TPrescripcionLentesContacto> lista = (ArrayList<TPrescripcionLentesContacto>) em
                .createQuery(
                        "Select a FROM TPrescripcionLentesContacto a "
                        + " LEFT JOIN FETCH a.TControl control "
                        + " WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TPrescripcionLentesContacto var = new TPrescripcionLentesContacto();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TPrescripcionMedica consultarPrescripcionMedica(TControl control) {
        List<TPrescripcionMedica> lista = (ArrayList<TPrescripcionMedica>) em
                .createQuery(
                        "Select a FROM TPrescripcionMedica a "
                        + " LEFT JOIN FETCH a.TControl control "
                        + " WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TPrescripcionMedica var = new TPrescripcionMedica();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TOftalmoscopia consultarOftalmoscopia(TControl control) {
        List<TOftalmoscopia> lista = (ArrayList<TOftalmoscopia>) em
                .createQuery(
                        "Select a FROM TOftalmoscopia a LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TOftalmoscopia var = new TOftalmoscopia();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TQueratometria consultarQueratometria(TControl control) {
        List<TQueratometria> lista = (ArrayList<TQueratometria>) em
                .createQuery(
                        "Select a FROM TQueratometria a LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TQueratometria var = new TQueratometria();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TRefraccion consultarRefraccion(TControl control) {
        List<TRefraccion> lista = (ArrayList<TRefraccion>) em
                .createQuery(
                        "Select a FROM TRefraccion a LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TRefraccion var = new TRefraccion();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TSubjetivo consultarSubjetivo(TControl control) {
        List<TSubjetivo> lista = (ArrayList<TSubjetivo>) em
                .createQuery(
                        "Select a FROM TSubjetivo a LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TSubjetivo var = new TSubjetivo();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TAfinacion consultarAfinacion(TControl control) {
        List<TAfinacion> lista = (ArrayList<TAfinacion>) em
                .createQuery(
                        "Select a FROM TAfinacion a LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TAfinacion var = new TAfinacion();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TAdicion consultarAdicion(TControl control) {
        List<TAdicion> lista = (ArrayList<TAdicion>) em
                .createQuery(
                        "Select a FROM TAdicion a LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TAdicion var = new TAdicion();
        var.setTControl(control);
        return var;

    }

    @SuppressWarnings("unchecked")
    public TDiagnosticoManejo consultarDiagnosticoManejo(TControl control) {
        List<TDiagnosticoManejo> lista = (ArrayList<TDiagnosticoManejo>) em
                .createQuery(
                        "Select a FROM TDiagnosticoManejo a LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TDiagnosticoManejo var = new TDiagnosticoManejo();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public List<TDiagnostico> consultarDiagnosticos(TDiagnosticoManejo diagnosticoManejo) {
        List<TDiagnostico> lista = (ArrayList<TDiagnostico>) em
                .createQuery(
                        "Select a FROM TDiagnostico a "
                        + " LEFT JOIN FETCH a.TDiagnosticoManejo di "
                        + " LEFT JOIN FETCH a.TPatologia patologia "
                        + " WHERE di.idDiagnosticoMedico =:idDiagnosticoMedico ")
                .setParameter("idDiagnosticoMedico", diagnosticoManejo.getIdDiagnosticoMedico())
                .getResultList();

        return lista;
    }

    @SuppressWarnings("unchecked")
    public TExamenMotor consultarExamenMotor(TControl control) {
        List<TExamenMotor> lista = (ArrayList<TExamenMotor>) em
                .createQuery(
                        "Select a FROM TExamenMotor a LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TExamenMotor var = new TExamenMotor();
        var.setTControl(control);
        return var;
    }

    @SuppressWarnings("unchecked")
    public TMicroscopia consultarBiomicroscopia(TControl control) {
        List<TMicroscopia> lista = (ArrayList<TMicroscopia>) em
                .createQuery(
                        "Select a FROM TMicroscopia a LEFT JOIN FETCH a.TControl control WHERE control.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();

        if (lista != null && !lista.isEmpty()) {
            return lista.get(0);
        }

        TMicroscopia var = new TMicroscopia();
        var.setTControl(control);
        return var;

    }

    private void validarControl(TControl control, TProfesional user) {
        if (control.getIdControl() == null) {
            control.setUserCreacion(user.getUserName());
            control.setFechaCreacion(Calendar.getInstance().getTime());
            em.persist(control);
        }
    }

    @SuppressWarnings("unchecked")
    public boolean validarModificacion(TControl control) {

        List<TConstante> constante_tiempo = (ArrayList<TConstante>) em.createQuery(
                "select t from TConstante t "
                + " WHERE t.nombre =:nombre_constante ")
                .setParameter("nombre_constante", Constantes.TIEMPO_MODIFICACION_CONTROL)
                .getResultList();

        if (constante_tiempo == null || constante_tiempo.isEmpty()) {
            return true;
        }

        Double tiempoModificacion = Double.parseDouble(constante_tiempo.get(0).getValor());
        return tiempoModificacion >= DateUtils.diferenciaEnHoras(control.getFeControl(), Calendar.getInstance().getTime());
    }

    @SuppressWarnings("unchecked")
    public List<TCatalogoMedicamento> buscarMedicamentos(TCatalogoMedicamento medicamentoSearch) {
        StringBuilder consulta = new StringBuilder(
                ConsultasDinamicasConstants.CONSULTAR_MEDICAMENTO);

        boolean isAllNull = true;
        HashMap<String, Object> parametros = new HashMap<String, Object>();

        if (medicamentoSearch.getTipoMed() != null) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_MEDICAMENTO_PARAM_TIPO_MEDICAMENTO);
            parametros.put("tipoMed", medicamentoSearch.getTipoMed());
            isAllNull = false;
        }

        if (medicamentoSearch.getNomGen() != null && medicamentoSearch.getNomGen().trim().length() > 0) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_MEDICAMENTO_PARAM_GENERICO);
            parametros.put("nomGen", medicamentoSearch.getNomGen());
            isAllNull = false;
        }

        if (medicamentoSearch.getDesPres() != null) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_MEDICAMENTO_PARAM_PRESENTACION);
            parametros.put("desPres", medicamentoSearch.getDesPres());
            isAllNull = false;
        }

        if (medicamentoSearch.getNomCom() != null && medicamentoSearch.getNomCom().trim().length() > 0) {
            consulta.append(isAllNull ? ConsultasDinamicasConstants.WHERE
                    : ConsultasDinamicasConstants.AND);
            consulta.append(ConsultasDinamicasConstants.CONSULTAR_MEDICAMENTO_PARAM_COMERCIAL);
            parametros.put("nomCom", medicamentoSearch.getNomCom());
            isAllNull = false;
        }
        consulta.append(ConsultasDinamicasConstants.CONSULTAR_MEDICAMENTO_PARAM_ORDER_BY);

        Query query = em.createQuery(consulta.toString());
        Set<String> keys = parametros.keySet();
        for (String llave : keys) {
            query.setParameter(llave, parametros.get(llave));
        }

        return (ArrayList<TCatalogoMedicamento>) query.getResultList();
    }

    @SuppressWarnings("unchecked")
    public TControl obtenerUltimoControlPersona(TPersona persona) {
        List<TControl> controles = (ArrayList<TControl>) em.createQuery(
                "select c from TControl c "
                + " WHERE c.tPersona.idPersona =:idPersona ORDER BY c.feControl DESC")
                .setParameter("idPersona", persona.getIdPersona())
                .getResultList();

        if (controles == null || controles.isEmpty()) {
            return null;
        }
        return controles.get(0);
    }

    @SuppressWarnings("unchecked")
    public List<TMedicamento> obtenerMedicamentosPersona(TControl control) {

        List<TMedicamento> medicamentos = (ArrayList<TMedicamento>) em.createQuery(
                "select t from TMedicamento t LEFT JOIN FETCH t.catalogo cat"
                + " WHERE t.prescripcion.TControl.idControl =:idControl ")
                .setParameter("idControl", control.getIdControl())
                .getResultList();
        return medicamentos;
    }

    /*public void generarReporte() throws JRException, IOException{
     List<TPersona> listaPersonas = buscarPersona(new TPersona());
     ReportUtils.generarRips(listaPersonas);
		
     }*/
}
